#ifndef TOKEN_SETS_HPP
#define TOKEN_SETS_HPP

#include "tokens.hpp"
#include <cstring>

struct TknSets
{
	bool Statement[Tkn::TokenCount];
	bool Expression[Tkn::TokenCount];
	bool PrimaryExpression[Tkn::TokenCount];
	bool Value[Tkn::TokenCount];
	bool UnaryOperator[Tkn::TokenCount];
	bool BinaryOperator[Tkn::TokenCount];

	TknSets()
	{
#define CLEAR( L ) memset( L, false, Tkn::TokenCount * sizeof(bool) );
#define ADD( DEST, SOURCE ) for ( int i = 0; i < Tkn::TokenCount; ++i ) { DEST[i] = DEST[i] || SOURCE[i]; };
		
		CLEAR( Value );
		Value[ Tkn::NumVal ] = true;
		Value[ Tkn::IntVal ] = true;
		Value[ Tkn::StringVal ] = true;
		
		CLEAR( UnaryOperator );
		UnaryOperator[ Tkn::Plus ] = true;
		UnaryOperator[ Tkn::Minus ] = true;
		
		CLEAR( BinaryOperator );
		BinaryOperator[ Tkn::Plus ] = true;
		BinaryOperator[ Tkn::Minus ] = true;

		CLEAR( PrimaryExpression );
		ADD( PrimaryExpression, Value );
		ADD( PrimaryExpression, UnaryOperator );
		PrimaryExpression[ Tkn::LParen ] = true;
		PrimaryExpression[ Tkn::Identifier ] = true;
		PrimaryExpression[ Tkn::If ] = true;
		
		CLEAR( Expression );
		ADD( Expression, PrimaryExpression );
		
		CLEAR( Statement );
		ADD( Statement, Expression );
		Statement[ Tkn::LCurlyBrace ] = true;
		Statement[ Tkn::Var ] = true;
		Statement[ Tkn::Do ] = true;
		Statement[ Tkn::While ] = true;
		Statement[ Tkn::Return ] = true;
		
#undef CLEAR
	}
	

};

#endif // TOKEN_SETS_HPP
